﻿$(function () {
    
    $.privateData = function ()
    {
        var outerSelector;
        var innerSelector;
        var innerSelectorSize;

        var previousStartPos = null;
        var previousEndPos = null;
    }
    
    $.widget('custom.timeline', {
        options: {
            type: "year", 
            name: "",
            customList: [],
            firstYear: 2012,
            lastYear: 2112,
            monthFrom: "January", 
            monthTo: "December",
            onselect: function () { },
            onunselect : function() { }
        },
        _create: function () {

            this.privateData = new $.privateData();
            
            this.element.addClass("custom-timeline");
            //Define all variables
            this.element.append('<div id="' + this.options.name + 'outer" style="height: 30px; cursor: pointer;"><div id="' + this.options.name + 'inner" style="height: 30px;overflow: hidden;"></div></div>');
            this.privateData.outerSelector = $('#' + this.options.name + 'outer');
            this.privateData.innerSelector = $('#' + this.options.name + 'inner');
            this.privateData.innerSelectorSize = 0;

            console.log(this);
        },
        _init: function () {
            var that = this;
            this.element.addClass("custom-timeline");
            //Define all variables
            this.element.append('<div id="' + this.options.name + 'outer" style="height: 30px; cursor: pointer;"><div id="' + this.options.name + 'inner" style="height: 30px;overflow: hidden;"></div></div>');

            this.privateData.outerSelector = $('#' + this.options.name + 'outer');
            this.privateData.innerSelector = $('#' + this.options.name + 'inner');
            this.privateData.innerSelectorSize = 0;
            //Set the number of arguments value to 0
            var numberOfElements = 0;

            switch (this.options.type.toLowerCase())
            {
                case "year":
                    //fill the inner element with years.
                    for (var i = this.options.firstYear; i <= this.options.lastYear; i++) {
                        that.privateData.innerSelector.append('<div id="' + i + '" style="display: inline; margin-left:10px; margin-right: 10px; font-size: 25px;">' + i + '</div>');
                        numberOfElements++;
                        that.privateData.innerSelectorSize += parseInt($('#' + i).css('width').replace('px', ''), 10) + parseInt($('#' + i).css('margin-left').replace('px', ''), 10) + parseInt($('#' + i).css('margin-right').replace('px', ''), 10);
                        $('#' + i).click(function () { that._click($(this).prop('id')) });
                        //generateInnerTag(that.privateData.innerSelector, that.privateData.innerSelectorSize, i, numberOfElements);
                    }
                    break;
                case "month":
                    //fill the inner element with Month.
                    var monthListToDisplay = new Array();
                    monthListToDisplay = getMonthList(this.options.monthFrom, this.options.monthTo)
                    $.each(monthListToDisplay,  (function () {
                        that.privateData.innerSelector.append('<div id="' + this.toString() + '" style="display: inline; margin-left:10px; margin-right: 10px; font-size: 25px;">' + this.toString() + '</div>');
                        numberOfElements++;
                        that.privateData.innerSelectorSize += parseInt($('#' + this.toString()).css('width').replace('px', ''), 10) + parseInt($('#' + this.toString()).css('margin-left').replace('px', ''), 10) + parseInt($('#' + this.toString()).css('margin-right').replace('px', ''), 10);
                        $('#' + this.toString()).click(function () { that._click($(this).prop('id')) });
                        //generateInnerTag(that.privateData.innerSelector, that.privateData.innerSelectorSize, this.toString(), numberOfElements);
                    }));
                    break;
                case "custom":
                    //fill the inner element with a custom list array
                    var list = new Array();
                    list = this.options.customlist;
                    $.each(list, (function () {
                        that.privateData.innerSelector.append('<div id="' + this.toString() + '" style="display: inline; margin-left:10px; margin-right: 10px; font-size: 25px;">' + this.toString() + '</div>');
                        numberOfElements++;
                        that.privateData.innerSelectorSize += parseInt($('#' + this.toString()).css('width').replace('px', ''), 10) + parseInt($('#' + this.toString()).css('margin-left').replace('px', ''), 10) + parseInt($('#' + this.toString()).css('margin-right').replace('px', ''), 10);
                        $('#' + this.toString()).click(function () { that._click($(this).prop('id')) });
                        //generateInnerTag(that.privateData.innerSelector, that.privateData.innerSelectorSize, this.toString(), numberOfElements);
                    }));
                    break;
            }
            
            //Determine the size of an element for the grid
            var elementSize = this.privateData.innerSelectorSize / (numberOfElements);
            this.privateData.innerSelector.css("width", this.privateData.innerSelectorSize);

            //Set the innerSelector to draggable ui event
            this.privateData.innerSelector.draggable({
                axis: "x",
                grid: [elementSize]
            });

            /*-----------------------------------------------------------------------------------
                EVENT FIRED WHEN USER UNCLICK ON A BUTTON OF THE MOUSE 
                HAS EFFECT TO RESET THE POSITION OF THE DRAGABBLE COMPONENT IN WRONG CASES 
            -----------------------------------------------------------------------------------*/
            this.privateData.innerSelector.mouseup(function () {
                manageSliding(that.privateData.outerSelector, that.privateData.innerSelector, that.privateData.innerSelectorSize, that.privateData.previousStartPos, that.privateData.previousEndPos);
            });

            /*-------------------------------------------------------------------------------------------------------------------
                IN SOME CASES WHEN USER LEAVE COMPONENT WITH THE MOUSE SO WE HAVE TO RESET POSITION OF THE DRAGGABLE COMPONENT
            ---------------------------------------------------------------------------------------------------------------------*/
            this.privateData.innerSelector.mouseleave(function () {
                manageSliding(that.privateData.outerSelector, that.privateData.innerSelector, that.privateData.innerSelectorSize, that.privateData.previousStartPos, that.privateData.previousEndPos);
            });

            /*-------------------------------------------------------------------------------------------------------------------
                WHEN USER ENTER IN THE COMPONENT SOME TIME INNERSELECTOR WILL BE RELPLACED - ALSO SOME BUGS WITH IT
            ---------------------------------------------------------------------------------------------------------------------*/
            this.privateData.innerSelector.mouseenter(function () {
                manageSliding(that.privateData.outerSelector, that.privateData.innerSelector, that.privateData.innerSelectorSize, that.privateData.previousStartPos, that.privateData.previousEndPos);
            });

            /*BUG : WHEN USER LEAVE THE COMPONENT WITH MOUSE BUTTON PRESSED MOUSELEAVE EVENT DO NOT FIRE - I DON'T KNOW HOW TO RESOLVE*/

        },
        _destroy: function () {
            
        },
        _click: function (id) {
            if ($('#' + id).hasClass('selected'))
            {
                this.options.onunselect(id);
            }
            else
            {   
                this.options.onselect(id);
            }
        }
    });

    /*That function is used to manage the month list*/
    function getMonthList(MonthFrom, MonthTo) {
        /*define the variables used to correspond to the month*/
        var firstMonthNumber;
        var lastMonthNumber;

        var MonthListEN = new Array();
        MonthListEN = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
        var MonthListFR = new Array();
        MonthListFR = ['Janvier', 'Fevrier', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'Decembre'];

        /*attibute the number of the months corresponding*/
        firstMonthNumber = getMonthNumber(MonthFrom);
        lastMonthNumber = getMonthNumber(MonthTo);
        var tempMonth = new Array();
        for (var i = firstMonthNumber; i <= lastMonthNumber; i++)
        {
            tempMonth[i] = MonthListFR[i]
        }
        return tempMonth;
    };

    /*That function is used to get the month number in the list of Month*/
    function getMonthNumber(month)
    {
        switch (month.toLowerCase()) {
            case 'january': return 0; break;
            case 'february': return 1; break;
            case 'march': return 2; break;
            case 'april': return 3; break;
            case 'may': return 4; break;
            case 'june': return 5; break;
            case 'july': return 6; break;
            case 'august': return 7; break;
            case 'september': return 8; break;
            case 'october': return 9; break;
            case 'novemeber': return 10; break;
            case 'december': return 11; break;
        };
    }

    /*Function used to manage the slide*/
    function manageSliding(outerSelector, innerSelector, innerSelectorSize, previousStartPos, previousEndPos)
    {
        var outerStartPos = outerSelector.position().left;
        var outerEndPos = outerSelector.position().left + outerSelector.width();

        var innerStartPos = innerSelector.position().left;
        var innerEndPos = innerSelector.position().left + innerSelector.width(); 

        //Initialize the previous Positions
        if (previousStartPos === null) {
            previousStartPos = innerStartPos;
        }
        if (previousEndPos === null) {
            previousEndPos = innerEndPos;
        }

        //Lock position
        if (innerStartPos > outerStartPos) {
            innerSelector.attr("style", 'left: ' + 0 + 'px; position: relative; height:30px;overflow: hidden;');
            innerSelector.css("width", innerSelectorSize);
            innerStartPos = innerSelector.position().left;
        }
        if (innerEndPos < outerEndPos && innerSelector.width() >= outerSelector.width()) {
            innerSelector.attr("style", 'left: ' + (innerStartPos + ((outerEndPos - outerStartPos) - innerEndPos)) + 'px; position: relative; height:30px;overflow: hidden;');
            innerSelector.css("width", innerSelectorSize);
            innerStartPos = innerSelector.position().left;
        }

        //Fill previous position for next time.
        previousStartPos = innerStartPos;
        previousEndPos = innerEndPos;
    }

    /*Function used to generate tags for the inner HTML*/
    function generateInnerTag(innerSelector, innerSelectorSize, tagName, numberOfElements)
    {
        innerSelector.append('<div id="' + tagName + '" style="display: inline; margin-left:10px; margin-right: 10px; font-size: 25px;">' + tagName + '</div>');
        numberOfElements++;
        innerSelectorSize += parseInt($('#' + tagName).css('width').replace('px', ''), 10) + parseInt($('#' + tagName).css('margin-left').replace('px', ''), 10) + parseInt($('#' + tagName).css('margin-right').replace('px', ''), 10);
        $('#' + tagName).click(function () {that._click($(this).prop('id')) });
    }
});